package gqz.testdemo.Bluetooth;

import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanResult;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.provider.Settings;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.UUID;

import gqz.testdemo.R;
import pub.devrel.easypermissions.EasyPermissions;
import pub.devrel.easypermissions.PermissionRequest;

/**
 * Created by Administrator on 2018/8/14.
 */

public class BleClient extends Activity implements EasyPermissions.PermissionCallbacks {

    String TAG = "BLEDemo-->";

    Switch switch_ble, switch_search;
    Button btn_search;
    TextView tv_name, tv_content;
    ListView lv;
    ProgressBar pb;
    EditText et;

    BluetoothManager bm;
    BluetoothAdapter ba;
    BluetoothLeScanner scan;
    BluetoothGatt mGatt;
    BluetoothDevice connDev;

    BleDevAdapter devAdapter;
    AlertDialog connectDialog;

    boolean isSupportBle = true;
    boolean bleEnable = false;

    ArrayList<BluetoothDevice> bleDevices = new ArrayList<>();
    String[] permissions = {Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION};

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_ble);
        checkPermission();
        initView();
        initBle();
        getBleOpenStatus();
        getBleName();
        getAllowSearchStatus();
    }

    private void checkPermission() {
        /*//请求权限
        if (EasyPermissions.hasPermissions(this, permissions)) {
        } else {
            //第二个参数是提示信息
            EasyPermissions.requestPermissions(this, "请给予位置权限,否则app无法正常运行", 001, permissions);
        }*/

        EasyPermissions.requestPermissions(
                new PermissionRequest.Builder(this, 001, permissions)
                        .setRationale("请给予位置权限,否则app无法正常运行")
                        .setPositiveButtonText("授权")
                        .setNegativeButtonText("拒绝")
                        .build());
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        // Forward results to EasyPermissions
        EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
    }

    @Override
    public void onPermissionsGranted(int requestCode, List<String> list) {
        for (String s : list) {
            Log.i(TAG, "onPermissionsGranted: requestCode:" + requestCode + " string:" + s);
        }
    }

    @Override
    public void onPermissionsDenied(int requestCode, List<String> list) {
        for (String s : list) {
            Log.i(TAG, "onPermissionsGranted: requestCode:" + requestCode + " string:" + s);
        }
    }

    private void checkGPS() {
        LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        boolean gps = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
        boolean network = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
        if (gps || network) {
            return;
        }
        Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
        startActivityForResult(intent, 123);
    }

    private void initView() {
        switch_ble = findViewById(R.id.ble_switch_ble);
        switch_search = findViewById(R.id.ble_switch_AllowSearch);
        btn_search = findViewById(R.id.ble_btn_search);
        pb = findViewById(R.id.ble_pb);
        lv = findViewById(R.id.ble_lv);
        lv.setOnItemClickListener(itemClick);
        tv_name = findViewById(R.id.ble_tv_name);
        tv_content = findViewById(R.id.ble_tv_content);
        et = findViewById(R.id.ble_et_send);
        tv_name.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showRenameDialog();
            }
        });

        switch_ble.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                setBleOpenStatus();
            }
        });
        switch_search.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
//                Log.i(TAG, "onClick: check status:"+switch_search.isChecked());
                if (switch_search.isChecked()) {
                    openAllowSearch(300);
                } else {
                    closeAllowSearch();
                }
            }
        });

        if (devAdapter == null)
            devAdapter = new BleDevAdapter(BleClient.this, bleDevices);
        lv.setAdapter(devAdapter);
    }

    public void initBle() {
        // 检查当前手机是否支持BLE
        if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
            Log.d(TAG, "initBle: 设备支持BLE");
            isSupportBle = true;
        } else {
            Toast.makeText(this, "设备不支持BLE", Toast.LENGTH_SHORT).show();
            isSupportBle = false;
        }
        bm = (BluetoothManager) getSystemService(BLUETOOTH_SERVICE);//这里与标准蓝牙略有不同
        ba = bm.getAdapter();
//        ba = BluetoothAdapter.getDefaultAdapter();//搜索不到设备 api < 18 使用
        scan = ba.getBluetoothLeScanner();

        IntentFilter i = new IntentFilter();
        i.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
        i.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
        i.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
        i.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        i.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
        i.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
        registerReceiver(receiver, i);

        IntentFilter filter = new IntentFilter();
        filter.addAction(BluetoothDevice.ACTION_FOUND);
        registerReceiver(devReceiver, filter);

//        String localMAC = android.provider.Settings.Secure.getString(this.getContentResolver(), "bluetooth_address");
//        appendStr("本机蓝牙名称：" + ba.getName() + "\n");
//        appendStr("本机蓝牙地址：" + localMAC);
        getBondedBluetooth();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(receiver);
        unregisterReceiver(devReceiver);
    }

    public void appendStr(String txt) {
        tv_content.append(txt);
    }

    //获取系统保存的成功配对过的设备，进行连接
    public void getBondedBluetooth() {
        Set<BluetoothDevice> devs = ba.getBondedDevices();
        for (BluetoothDevice dev : devs) {
            addDevByFilter(dev);
        }
    }

    //显示重命名弹窗
    public void showRenameDialog() {
        AlertDialog.Builder b = new AlertDialog.Builder(this);
        b.setTitle("修改本机名称");
        final EditText et = new EditText(this);
        et.setText(tv_name.getText().toString());
        b.setView(et);
        b.setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        });
        b.setPositiveButton("修改", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                ba.setName(et.getText().toString());
                dialog.dismiss();
                getBleName();
            }
        });
        b.create().show();
    }

    //获取蓝牙开关
    public void getBleOpenStatus() {
        bleEnable = ba.isEnabled();
        switch_ble.setChecked(bleEnable);
    }

    //设置蓝牙开关
    public void setBleOpenStatus() {
        if (bleEnable)
            ba.disable();
        else
            ba.enable();
        switch_ble.setEnabled(false);
    }

    //获取允许检测状态
    public void getAllowSearchStatus() {
        int mode = ba.getScanMode();
        Log.i(TAG, "getAllowSearchStatus: scanMode=" + mode);
        switch (mode) {
            case BluetoothAdapter.SCAN_MODE_CONNECTABLE:
                Log.i(TAG, "getAllowSearchStatus: 不可见");
                switch_search.setChecked(false);
                break;
            case BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE:
                Log.i(TAG, "getAllowSearchStatus: 可见");
                switch_search.setChecked(true);
                break;
        }
    }

    //开启允许检测
    public void openAllowSearch() {
        //启动修改蓝牙可见性的Intent
        Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
        //设置蓝牙可见性的时间，方法本身规定最多可见300秒
        intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
        startActivity(intent);
    }

    public void openAllowSearch(int timeout) {
        try {
            Method setDiscoverableTimeout = BluetoothAdapter.class.getMethod("setDiscoverableTimeout", int.class);
            setDiscoverableTimeout.setAccessible(true);
            Method setScanMode = BluetoothAdapter.class.getMethod("setScanMode", int.class, int.class);
            setScanMode.setAccessible(true);

            setDiscoverableTimeout.invoke(ba, timeout);
            setScanMode.invoke(ba, BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE, timeout);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //关闭允许检测
    public void closeAllowSearch() {
        try {
            Method setDiscoverableTimeout = BluetoothAdapter.class.getMethod("setDiscoverableTimeout", int.class);
            setDiscoverableTimeout.setAccessible(true);
            Method setScanMode = BluetoothAdapter.class.getMethod("setScanMode", int.class, int.class);
            setScanMode.setAccessible(true);

            setDiscoverableTimeout.invoke(ba, 1);
            setScanMode.invoke(ba, BluetoothAdapter.SCAN_MODE_CONNECTABLE, 1);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //获取本机蓝牙名称
    public void getBleName() {
        tv_name.setText(ba.getName());
    }

    //设置本机蓝牙名称
    public void setBleName(String name) {
        ba.setName(name);
        getBleName();
    }

    //搜索设备
    public void searchDev() {
        if (ba == null) {
            Log.e(TAG, "searchDev: bluetoothAdapter is null !");
            return;
        }
        Log.i(TAG, "searchDev: ");
//        if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) {// <=6.0
//            ba.startLeScan(leScanCallback);//扫描ble蓝牙，过时
//        } else {// >=7.0
//            if (scan != null)
//                scan.startScan(scanCallback);//扫描ble蓝牙
//            else Log.e(TAG, "searchDev: ble not support!");
//        }
        ba.startDiscovery();//扫描传统蓝牙
        btn_search.setEnabled(false);
        pb.setVisibility(View.VISIBLE);
    }

    //停止搜索
    public void stopSearch() {
        Log.i(TAG, "stopSearch: ");
//        if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) {// <=6.0
//            ba.stopLeScan(leScanCallback);
//        } else {// >=7.0
//            if (scan != null)
//                scan.stopScan(scanCallback);//扫描ble蓝牙
//            else Log.e(TAG, "searchDev: ble not support!");
//        }
        ba.cancelDiscovery();
        btn_search.setEnabled(true);
        pb.setVisibility(View.INVISIBLE);
    }

    public void addDevByFilter(BluetoothDevice dev) {
        Log.i(TAG, "onReceive: name:" + dev.getName() + " address:" + dev.getAddress());
        boolean flag = false;
        String addr = dev.getAddress();
        BluetoothDevice rawDev = null;
        for (BluetoothDevice bd : bleDevices) {
            if (bd.getAddress().equals(addr)) {
                flag = true;
                rawDev = bd;
                break;
            }
        }
        if (!flag)
            bleDevices.add(dev);
        if (rawDev != null) {
            if (dev.getName() != null && !dev.getName().equals(rawDev.getName()))
                bleDevices.set(bleDevices.indexOf(rawDev), dev);
        }
    }

    //配对设备
    public void connectDev(BluetoothDevice dev) {
        connDev = ba.getRemoteDevice(dev.getAddress());
        switch (connDev.getType()) {
            case BluetoothDevice.DEVICE_TYPE_UNKNOWN:
                Log.w(TAG, "connectDev: 未知类型设备");
                break;
            case BluetoothDevice.DEVICE_TYPE_CLASSIC:
                Log.w(TAG, "connectDev: BR/EDR设备");
                break;
            case BluetoothDevice.DEVICE_TYPE_LE:
                Log.w(TAG, "connectDev: LE设备");
                break;
            case BluetoothDevice.DEVICE_TYPE_DUAL:
                Log.w(TAG, "connectDev: 双模式设备");
                break;
        }
        boolean isBond = false;
        switch (connDev.getBondState()) {
            case BluetoothDevice.BOND_NONE://未配对，先配对，再连接
                Toast.makeText(BleClient.this, "正在配对...", Toast.LENGTH_SHORT).show();
                isBond = connDev.createBond();//配对，方便下次直接连接（可选）
                Log.d(TAG, "connectDev: bond:" + isBond);
                if (connDev != null && isBond) {
                    Toast.makeText(BleClient.this, "配对成功，正在连接...", Toast.LENGTH_SHORT).show();
//                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
//                        mGatt = connDev.connectGatt(this, false, gattCallback, BluetoothDevice.TRANSPORT_LE);
//                    else
//                    mGatt = connDev.connectGatt(this, false, gattCallback);
                }
                break;
            case BluetoothDevice.BOND_BONDED://已配对，直接连接
                Toast.makeText(BleClient.this, "已配对，正在连接...", Toast.LENGTH_SHORT).show();
                if (connDev != null)
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
                        mGatt = connDev.connectGatt(this, false, gattCallback, BluetoothDevice.TRANSPORT_LE);
                    else
                        mGatt = connDev.connectGatt(this, false, gattCallback);
//                    mGatt = connDev.connectGatt(this, false, gattCallback);
                break;
        }
        /*Toast.makeText(BLEDemo.this, "正在连接...", Toast.LENGTH_SHORT).show();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
            mGatt = connDev.connectGatt(this, false, gattCallback, BluetoothDevice.TRANSPORT_LE);
        else
            mGatt = connDev.connectGatt(this, false, gattCallback);*/
    }

    //取消连接
    public boolean disconnectDev() {
        if (mGatt == null) return false;
        mGatt.disconnect();
        mGatt.close();
        return true;
    }

    //取消配对
    public boolean unBondDev(BluetoothDevice dev) {
        try {
            Method removeBond = dev.getClass().getMethod("removeBond");
            return (boolean) removeBond.invoke(dev);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return false;
    }

    public void onClick(View view) {
        searchDev();
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                stopSearch();//一段时间后停止搜索，以防一直扫描耗电
            }
        }, 20 * 1000);
    }

    public void sendClick(View v) {

    }

    BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            switch (intent.getAction()) {
                case BluetoothAdapter.ACTION_STATE_CHANGED:
                    int blueState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, 0);
                    switch (blueState) {
                        case BluetoothAdapter.STATE_TURNING_ON:
                            Log.i(TAG, "onReceive: 蓝牙正在打开...");
                            bleEnable = false;
                            break;
                        case BluetoothAdapter.STATE_ON:
                            Log.i(TAG, "onReceive: 蓝牙已打开");
                            bleEnable = true;
                            getBleOpenStatus();
                            switch_ble.setEnabled(true);
                            break;
                        case BluetoothAdapter.STATE_TURNING_OFF:
                            Log.i(TAG, "onReceive: 蓝牙正在关闭...");
                            bleEnable = false;
                            getBleOpenStatus();
                            break;
                        case BluetoothAdapter.STATE_OFF:
                            Log.i(TAG, "onReceive: 蓝牙已关闭");
                            bleEnable = false;
                            switch_ble.setEnabled(true);
                            break;
                    }
                    break;
                case BluetoothAdapter.ACTION_SCAN_MODE_CHANGED:
                    Log.i(TAG, "onReceive: scan mode changed");
                    getAllowSearchStatus();
                    break;
                case BluetoothAdapter.ACTION_DISCOVERY_STARTED:
                    Log.i(TAG, "onReceive: discovery started");
                    break;
                case BluetoothAdapter.ACTION_DISCOVERY_FINISHED:
                    Log.i(TAG, "onReceive: discovery finished");
                    break;
                case BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED:
                    Log.i(TAG, "onReceive: connection state changed");
                    break;
                case BluetoothDevice.ACTION_BOND_STATE_CHANGED:
                    BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                    switch (device.getBondState()) {
                        case BluetoothDevice.BOND_NONE:
                            Log.e(getPackageName(), "取消配对");
                            break;
                        case BluetoothDevice.BOND_BONDING:
                            Log.e(getPackageName(), "配对中");
                            break;
                        case BluetoothDevice.BOND_BONDED:
                            Log.e(getPackageName(), "配对成功");
                            break;
                    }
                    break;
            }
        }
    };

    //搜索附近蓝牙设备结果广播
    BroadcastReceiver devReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);  //这个就是所获得的蓝牙设备。
                Log.i(TAG, "onReceive: name:" + device.getName() + " address:" + device.getAddress());
                addDevByFilter(device);
                devAdapter.notifyDataSetChanged();
                //name:hello address:54:C9:DF:59:59:8C
                //name:JDN-W09 address:88:44:77:54:3C:F4
            }
        }
    };

    BluetoothAdapter.LeScanCallback leScanCallback = new BluetoothAdapter.LeScanCallback() {
        @Override
        public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
            Log.i(TAG, "onLeScan: name:" + device.getName() + "  address:" + device.getAddress());
            addDevByFilter(device);
            devAdapter.notifyDataSetChanged();
        }
    };

    ScanCallback scanCallback = new ScanCallback() {

        @Override
        public void onScanResult(int callbackType, ScanResult result) {//单条搜索结果
            super.onScanResult(callbackType, result);
            BluetoothDevice dev = result.getDevice();
            Log.i(TAG, "onScanResult: name:" + dev.getName() + "  address(mac):" + dev.getAddress());
            addDevByFilter(dev);
            devAdapter.notifyDataSetChanged();
        }

        @Override
        public void onBatchScanResults(List<ScanResult> results) {//批量搜索结果
            super.onBatchScanResults(results);
            Log.i(TAG, "onBatchScanResults: ");
            for (ScanResult res : results) {
                BluetoothDevice dev = res.getDevice();
                Log.i(TAG, "onBatchScanResults: name:" + dev.getName() + "  address(mac):" + dev.getAddress());
                addDevByFilter(dev);
            }
            devAdapter.notifyDataSetChanged();
        }

        @Override
        public void onScanFailed(int errorCode) {//搜索失败
            super.onScanFailed(errorCode);
            Log.i(TAG, "onScanFailed: ");
        }
    };

    AdapterView.OnItemClickListener itemClick = new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            BluetoothDevice dev = (BluetoothDevice) devAdapter.getItem(position);
            connectDev(dev);
        }
    };

    //判断特征可读
    private boolean isReadCharacteristic(BluetoothGattCharacteristic characteristic) {
        return ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_READ) > 0);
    }

    //判断特征可写
    private boolean isWriteCharacteristic(BluetoothGattCharacteristic characteristic) {
        return ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE) > 0 ||
                (characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) > 0);
    }

    //判断特征可通知
    private boolean isNotifyCharacteristic(BluetoothGattCharacteristic characteristic) {
        return ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0 ||
                (characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_INDICATE) > 0);
    }

    //读取特征
    private void readCharacteristic(BluetoothGattCharacteristic characteristic) {
        mGatt.readCharacteristic(characteristic);
    }

    //写入特征
    private void writeCharacteristic(BluetoothGattCharacteristic characteristic) {
        characteristic.setValue("byte[] or String");
        mGatt.writeCharacteristic(characteristic);
    }

    //设置通知特征
    private void setCharacteristicNotify(BluetoothGattCharacteristic characteristic, boolean enable) {
        mGatt.setCharacteristicNotification(characteristic, enable);
        //在明确知道当前特征的描述符前提下，可以直接使用描述符，不需要做判断，
        //但如果不知道此特征是否具有描述符的情况下，没有以下几行代码可能会导致设置通知失败的情况发生。
        List<BluetoothGattDescriptor> descriptorList = characteristic.getDescriptors();
        if (descriptorList != null) {
            for (BluetoothGattDescriptor descriptor : descriptorList) {
                byte[] value = enable ? BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE : BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE;
                descriptor.setValue(value);
                mGatt.writeDescriptor(descriptor);
            }
        }
    }

    BluetoothGattCallback gattCallback = new BluetoothGattCallback() {

        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {//当设备与中心连接状态发生改变时。
            super.onConnectionStateChange(gatt, status, newState);
            Log.d(TAG, "onConnectionStateChange: gatt:" + gatt + " status:" + status + " newState:" + newState);
            switch (newState) {
                case BluetoothProfile.STATE_CONNECTED:
                    Log.d(TAG, "onConnectionStateChange: 连接成功");
                    mGatt.discoverServices();//连接成功，开始搜索该设备中的服务
                    break;
                case BluetoothProfile.STATE_DISCONNECTED:
                    Log.e(TAG, "onConnectionStateChange: 断开连接");
                    mGatt.close();
                    break;
            }
        }

        @Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {//当发现设备服务时，会回调到此处。
            super.onServicesDiscovered(gatt, status);
            Log.d(TAG, "onServicesDiscovered: ");
            if (status == BluetoothGatt.GATT_SUCCESS) {//找到服务
                Log.i(TAG, "onServicesDiscovered: 发现服务");
                //在这里可以对服务进行解析，寻找到你需要的服务
                List<BluetoothGattService> services = mGatt.getServices();
                for (BluetoothGattService service : services) {
                    UUID uuid = service.getUuid();
                    Log.i(TAG, "onServicesDiscovered: --------->>>>service.uuid=" + service.getUuid().toString());
                    List<BluetoothGattCharacteristic> characteristics = service.getCharacteristics();
                    for (BluetoothGattCharacteristic characteristic : characteristics) {
                        Log.i(TAG, "onServicesDiscovered: Characteristic.uuid=" + characteristic.getUuid().toString() +
                                " characteristic.properties=" + characteristic.getProperties() +
                                " characteristic.value=" + characteristic.getValue());
                        if (isReadCharacteristic(characteristic)) Log.d(TAG, "onServicesDiscovered: isReadCharacteristic");
                        if (isWriteCharacteristic(characteristic)) Log.d(TAG, "onServicesDiscovered: isWriteCharacteristic");
                        if (isNotifyCharacteristic(characteristic)) Log.d(TAG, "onServicesDiscovered: isNotifyCharacteristic");
                        for (BluetoothGattDescriptor desc : characteristic.getDescriptors()) {
                            Log.i(TAG, "onServicesDiscovered: descriptor.uuid" + desc.getUuid().toString() +
                                    " desc.value=" + desc.getValue());
                        }
                    }
                }
            } else {
                Log.w(TAG, "onServicesDiscovered: status:" + status);
            }
        }

        @Override
        public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {//读取特征后回调到此处。
            super.onCharacteristicRead(gatt, characteristic, status);
            Log.d(TAG, "onCharacteristicRead: ");
            if (status == BluetoothGatt.GATT_SUCCESS) {
                byte[] data = characteristic.getValue();
            } else {
                Log.w("TAG", "onCharacteristicRead fail-->" + status);
            }
        }

        @Override
        public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {//写入特征后回调到此处。
            super.onCharacteristicWrite(gatt, characteristic, status);
            Log.d(TAG, "onCharacteristicWrite: ");
            if (status == BluetoothGatt.GATT_SUCCESS) {
                // 发送成功

            } else {
                // 发送失败
            }
        }

        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {//当特征（值）发生变法时回调到此处。
            super.onCharacteristicChanged(gatt, characteristic);
            Log.d(TAG, "onCharacteristicChanged: ");
        }

        @Override
        public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {//读取描述符后回调到此处。
            super.onDescriptorRead(gatt, descriptor, status);
            Log.d(TAG, "onDescriptorRead: ");
            if (status == BluetoothGatt.GATT_SUCCESS) {
                // 发送成功

            } else {
                // 发送失败
            }
        }

        @Override
        public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) { //写入描述符后回调到此处
            super.onDescriptorWrite(gatt, descriptor, status);
            Log.d(TAG, "onDescriptorWrite: ");
            if (status == BluetoothGatt.GATT_SUCCESS) {
                // 发送成功

            } else {
                // 发送失败
            }
        }

        @Override
        public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {//Rssi表示设备与中心的信号强度，发生变化时回调到此处。
            super.onReadRemoteRssi(gatt, rssi, status);
            Log.d(TAG, "onReadRemoteRssi: rssi=" + rssi + " status=" + status);
        }

        @Override
        public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {//完成可靠的写入事务时调用回调。
            super.onReliableWriteCompleted(gatt, status);
            Log.d(TAG, "onReliableWriteCompleted: ");
        }
    };
}
